Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: subscription page #30551

Merged
merged 94 commits into from
Oct 31, 2023
Merged

feat: subscription page #30551

merged 94 commits into from
Oct 31, 2023

Conversation

hugocostadev
Copy link
Contributor

@hugocostadev hugocostadev commented Oct 2, 2023

Proposed changes (including videos or screenshots)

New Manage subscription page to allow admin users check usage of some services and manage the subscription of the workspace

Changes:

Front-end:

  • new page, route, admin item and Cards components for the new Manage subscription admin page
  • New FramedIcon component in ui-client package, should be moved to fuselage in the future
  • Added Box component props to Card components to give more flexibility on styling card elements due to design specs
  • new useIsSelfHosted.ts hook to check if server is running on cloud or not
  • changes to useLicense.ts hook to use the new license.info endpoint
  • new getDaysLeft.ts util function to check quantity of days given a specific date
  • new getPlanName.ts util function to retrieve the plan of the license given some condition related to activeModules, this function is necessary to prevent code repetition
  • fix useAdministrationItems.spec.ts unit test
  • moved useActiveConnections hook to hooks folder to be reused in other places
  • new GO links
  • renamed useAnalyticsObject.ts hook to useStatistics.ts to better describe its usage and moved to more appropiate folder hooks
  • new i18n translations
  • new custom hook useCheckoutURL.ts to get the new endpoint https://billing.rocket.chat/v2/checkout

Back-end:

  • new endpoint billing.checkoutUrl to get the checkout url provided by cloud
  • new function getCheckoutUrl.ts to fetch data from new billing service

image
image

TODO:

Issue(s)

Steps to test or reproduce

Further comments

NBJ-289

@changeset-bot
Copy link

changeset-bot bot commented Oct 2, 2023

🦋 Changeset detected

Latest commit: 4652b7f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 30 packages
Name Type
@rocket.chat/meteor Minor
@rocket.chat/core-typings Minor
@rocket.chat/rest-typings Minor
@rocket.chat/core-services Patch
@rocket.chat/cron Patch
@rocket.chat/gazzodown Major
@rocket.chat/livechat Patch
@rocket.chat/model-typings Patch
@rocket.chat/ui-contexts Major
@rocket.chat/account-service Patch
@rocket.chat/authorization-service Patch
@rocket.chat/ddp-streamer Patch
@rocket.chat/omnichannel-transcript Patch
@rocket.chat/presence-service Patch
@rocket.chat/queue-worker Patch
@rocket.chat/stream-hub-service Patch
@rocket.chat/api-client Patch
@rocket.chat/license Patch
@rocket.chat/omnichannel-services Patch
@rocket.chat/pdf-worker Patch
@rocket.chat/presence Patch
rocketchat-services Patch
@rocket.chat/ddp-client Patch
@rocket.chat/fuselage-ui-kit Major
@rocket.chat/models Patch
@rocket.chat/ui-client Major
@rocket.chat/ui-video-conf Major
@rocket.chat/uikit-playground Patch
@rocket.chat/web-ui-registration Major
@rocket.chat/instance-status Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov
Copy link

codecov bot commented Oct 2, 2023

Codecov Report

Merging #30551 (4652b7f) into develop (6167ddf) will decrease coverage by 9.06%.
Report is 1 commits behind head on develop.
The diff coverage is 72.72%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop   #30551      +/-   ##
===========================================
- Coverage    51.34%   42.28%   -9.06%     
===========================================
  Files          815      715     -100     
  Lines        15121    14078    -1043     
  Branches      2754     2692      -62     
===========================================
- Hits          7764     5953    -1811     
- Misses        6948     7778     +830     
+ Partials       409      347      -62     
Flag Coverage Δ
unit 64.42% <64.28%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

@hugocostadev hugocostadev added this to the 6.5.0 milestone Oct 4, 2023
@hugocostadev hugocostadev requested a review from ggazzo October 30, 2023 13:03
@ggazzo ggazzo force-pushed the feat/manage-subscription branch from c9ecb37 to d870b4b Compare October 31, 2023 03:44
Copy link
Member

@ggazzo ggazzo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please check the comments and commits, I believe I solved all the issues that I pointed, but still I commented just to make you aware about the improvements


const CardTitle: FC = ({ children }) => (
<Box mbe={12} fontScale='h4' color='default'>
const CardTitle: FC<ComponentProps<typeof Box>> = ({ children, ...props }) => (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think accepting properties here for styling violates our directives https://developer.rocket.chat/fuselage-design-system/componentization

Comment on lines 46 to 57
const getHeaderButtons = () => {
return (
<ButtonGroup>
{isRegistered || (isRegistered && subscriptionSuccess) ? (
<Button icon={syncLicenseUpdate.isLoading ? undefined : 'reload'} onClick={() => handleSyncLicenseUpdateClick()}>
{syncLicenseUpdate.isLoading ? <Throbber size='x12' inheritColor /> : t('Sync_license_update')}
</Button>
) : null}
<UpgradeButton primary mis={8} i18nKey={isEnterprise ? 'Manage_subscription' : 'Upgrade'} />
</ButtonGroup>
);
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no good reason to create a function to return this component

Comment on lines 17 to 41
const getEnterpriseSectionContent = () => {
const enterpriseModules = [
'scalability',
'accessibility-certification',
'engagement-dashboard',
'oauth-enterprise',
'custom-roles',
'auditing',
];

if (!isEnterprise) {
return enterpriseModules.map((module) => {
return { title: t(`UpgradeToGetMore_${module}_Title`), body: t(`UpgradeToGetMore_${module}_Body`) };
});
}

const missingModules = enterpriseModules.filter((module) => !activeModules.includes(module));

return missingModules.map((module) => {
return {
title: t(`UpgradeToGetMore_${module}_Title`),
body: t(`UpgradeToGetMore_${module}_Body`),
};
});
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why testing if its enterprise here? why not just filtering by the missing modulues?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the CE will not have modules

Comment on lines 73 to 77
<Trans i18nKey='Compare_plans'>
<Button is='a' external href={PRICING_LINK}>
Compare plans
</Button>
</Trans>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t('Compare_plans')


return (
<FeatureUsageCard card={card}>
{MACsCount !== undefined ? (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we dont have this info here, the parent page should be displaying the skeleton, no need to do this here

Comment on lines 15 to 18
const pieGraph = macLimit && {
used: macLimit?.value || 0,
total: macLimit.max || 100,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you already tested macLimit why macLimit?.... ?

@@ -97,7 +97,7 @@ const InformationPage = memo(function InformationPage({
</Grid.Item>
{!showSeatCap && (
<Grid.Item xl={12} height='50%'>
<SeatsCard seatsCap={seatsCap} />
<SeatsCard />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is going to be 'loading' forever

const getLicenses = useEndpoint('GET', '/v1/licenses.info');

const queryClient = useQueryClient();

const notify = useSingleStream('notify-all');

useEffect(() => notify('license', () => invalidateQueryClientLicenses(queryClient)), [notify, queryClient]);

return useQuery(['licenses', 'getLicenses'], () => getLicenses({}), {
const queryKey = params?.loadValues ? ['licenses', 'getLicensesWithValues'] : ['licenses', 'getLicenses'];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of using a different key why not just add a new parameter? this is going to break the invalidation

Comment on lines 52 to 56
useEffect(() => {
if (subscriptionSuccess && syncLicenseUpdate.isIdle) {
syncLicenseUpdate.mutate(undefined, { onSuccess: () => refetchLicense() });
}
}, [refetchLicense, subscriptionSuccess, syncLicenseUpdate]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is the recipe to create a loop. also there is no need to refetch the license, the license is invalidated through the stream

Comment on lines 1 to 5
export type BillingEndpoints = {
'/v1/billing.checkoutUrl': {
GET: () => { url: string };
};
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to add this type here, this is supposed to be something internal so we can declare it using augmentation

ggazzo
ggazzo previously approved these changes Oct 31, 2023
Comment on lines +31 to +32
if (!response.ok) {
throw new Error(await response.json());
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ggazzo I could not reproduce a scenario that got this error, because I didn't find a ok attribute in the payload ... Is this going to work? Maybe I've missed something

Comment on lines +83 to +84
{isLicenseLoading && <SubscriptionPageSkeleton />}
{!isLicenseLoading && (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know that some people prefer this way, but following our recommended best practices, this is not recommended...
https://alexkondov.com/tao-of-react/#conditional-rendering

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they suggests ternary to avoid zeros but here we are handling booleans we should be fine :)

</CardBody>
{showUpgradeButton && (
<CardFooter>
{' '}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this necessary?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really, prettier doing pretty stuff

@ggazzo ggazzo dismissed KevLehman’s stale review October 31, 2023 15:52

thanks for the review

@ggazzo ggazzo merged commit a31d533 into develop Oct 31, 2023
@ggazzo ggazzo deleted the feat/manage-subscription branch October 31, 2023 16:24
hugocostadev added a commit that referenced this pull request Oct 31, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants